#include "FileNode.h"
#include "Utils.h"
/*---------------------------------------------------------------------------*/
FileNode::FileNode(string name, FileNode *p)
{
	strName = name;
	parent = p;
	childs.clear();
	bDone = false;
	size = 0;
}
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
FileNode::~FileNode()
{
	
	for(unsigned int i=0; i<childs.size(); i++)
	{
		delete childs[i];
	}

}
/*---------------------------------------------------------------------------*/
string FileNode::getName()
{
	return strName;	
}
/*---------------------------------------------------------------------------*/
string FileNode::getAbsolutePath()
{
	if(parent) return parent->getAbsolutePath() + "/" + strName;

	return strName;	
}
/*---------------------------------------------------------------------------*/
string FileNode::getExtension()
{

	if(isFolder()) return "";	
	
	string ret;
	
	size_t i = strName.find_last_of('.');
	if( i == string::npos ) return "";
	ret = strName.substr(i+1);
	
	return ret;
}
/*---------------------------------------------------------------------------*/
void FileNode::addChild(FileNode *ch)
{
	if( getChild(ch->getName()) )
	{
		cout << "THIS MESSAGE SHOULD NOT BE SHOWN!!" << endl;
		delete ch;
	}
	else
	{
		childs.push_back( ch );
	}
}
/*---------------------------------------------------------------------------*/
void FileNode::clear()
{
	
	
	for(unsigned int i=0; i<childs.size(); i++)
	{
		delete childs[i];
	}
	
	childs.clear();
}
/*---------------------------------------------------------------------------*/
FileNode *FileNode::getChild(string str)
{
	string name2 = str;
	size_t pos = str.find("/");
	if( pos != string::npos ) name2 = str.substr(0,pos);
	
	for(unsigned int i=0; i<childs.size(); i++)
	{
		if( !childs[i]->getName().compare(name2) ) return childs[i];
	}
	
	return NULL;
}
/*---------------------------------------------------------------------------*/
FileNode *FileNode::add(string str)
{
	//DEBUGMSG("FileNode::add() : " << str << " -> " << this->getName());
	
	if( str == "" ) return this;
	
	size_t pos = str.find("/");
	bool bChilds = false;
	
	
	if( pos == 0 ) 
	{
		str = str.substr(1);
		pos = str.find("/");
	}
	
	if( pos != string::npos ) bChilds = true;
	
	
	if( pos == str.length() - 1) 
	{
		str = str.substr(0,str.length() - 1);
		bChilds = false;
	}
	
	if(bChilds)
	{
		string part1 = str.substr(0,pos);
		string part2 = str.substr(pos+1);
		
		FileNode *fn = this->getChild(part1);
		if( fn == NULL ) 
		{
			fn = new FileNode(part1,this);
			this->addChild(fn);
		}
		
		
		return fn->add(part2);
		
	}
	else
	{
		FileNode *fn = this->getChild(str);
		if( fn == NULL ) 
		{
			fn = new FileNode(str,this);
			this->addChild(fn);
			return fn;
		}
		else return fn;
		
	}
	
	
	return NULL;
}
/*---------------------------------------------------------------------------*/
void FileNode::show(int level)
{
	for(int i=0; i<level; i++) cout << i <<  " -";

	
	cout << strName << isDone() ;
	
	if(hasChilds() & isDone() ) 
		cout << " ( done:" << this->getNodesCount() << " subnodes )" << endl;
	else
		cout << endl;
	

	for(unsigned int i=0; i<childs.size(); i++)
	{
		childs[i]->show(level+1);
	}
}
/*---------------------------------------------------------------------------*/
FileNode *FileNode::getFirstChild()
{
	if(  childs.size() < 1 ) return NULL;
	currentChild = 0;
	return childs[0];
}
/*---------------------------------------------------------------------------*/
FileNode *FileNode::getNextChild()
{
	if( currentChild + 1 >= childs.size() ) return NULL;
	return childs[++currentChild];
}
/*---------------------------------------------------------------------------*/
bool FileNode::hasChilds()
{
	return (bool)childs.size();
}
/*---------------------------------------------------------------------------*/
bool FileNode::isFolder()
{
	return (type == 4) || (type == 0) || hasChilds();
}
/*---------------------------------------------------------------------------*/
FileNode *FileNode::getParent()
{
	return parent;
}
/*---------------------------------------------------------------------------*/
unsigned int FileNode::getNodesCount()
{
	unsigned int total = 0;
	
	for(unsigned int i=0; i<childs.size(); i++)
	{
		total++;
		total += childs[i]->getNodesCount();
	}
	
	return total;
}
/*---------------------------------------------------------------------------*/
void FileNode::setDone(bool d)
{
	bDone = d;
}
/*---------------------------------------------------------------------------*/
bool FileNode::isDone()
{
	bool ch = true;
	for(unsigned int i=0; i<childs.size(); i++)
	{
		if(!childs[i]->isDone()) ch = false;
	}
	if(bDone && ch) return true;
	
	
	if( bDone && !hasChilds() ) return true;
	
	return false;
}
/*---------------------------------------------------------------------------*/
bool FileNode::isFilled()
{
	return bDone;
}
/*---------------------------------------------------------------------------*/
void	FileNode::setSize(uli s)
{
	size = s;
}
/*---------------------------------------------------------------------------*/
uli	FileNode::getSize()
{
	return size;
}
/*---------------------------------------------------------------------------*/
// Total size in KiB
double FileNode::getChildsSize()
{
	double ret = 0;
	FileNode *child = getFirstChild();
	
	while(child)
	{
		ret += child->getSize() / (float)1024 ;
	
		child = getNextChild();
	}
	
	return ret;
}
/*---------------------------------------------------------------------------*/
// returns children count
uint FileNode::getChildsCount()
{
	return childs.size();
}
/*---------------------------------------------------------------------------*/
void	FileNode::setType(int s)
{
	type = s;
}
/*---------------------------------------------------------------------------*/
int FileNode::getType()
{
	return type;
}
/*---------------------------------------------------------------------------*/
